/* 
 * File:   main.cpp
 * Author: 
 *      
 *      Camila Monteiro Caetano Tomaz           RA: 48.184-0
 *      Icaro de Paula                          RA: 
 *      Jonas de Castro                         RA: 48.222-6
 *
 * Created on 7 de Maio de 2013, 11:35
 * 
 * Descrição:
 *      Programa desenvolvido para a disciplina de Estrutura de Dados.
 *      Montamos o jogo paciência spider, que é uma variação do jogo paciência.
 *      Para isto, utilizamos pilhas, vetores e filas, para simular as colunas
 *      de cartas utilizadas no jogo.
 * 
 */

#include <iostream> // Biblioteca cout
#include <stack> // Biblioteca pilha
#include <vector> // Biblioteca Vetor
#include <algorithm>    // Biblioteca random_shuffle
#include <ctime>        // Biblioteca time
#include <cstdlib>
#include <bits/stl_stack.h>      // Biblioteca rand, std::srand
#include <stdio.h>

using namespace std;
 
// Declarando a pilha que conterá as cartas que poderão vir para a mesa posteriormente.
stack<string> pilhaAuxiliar;
       
//Declarando a pilha que irá conter todas as cartas embaralhadas
stack<string> pilhaEmbaralhada;

//Declarando a pilha utilizada para a movimentação das cartas entre uma pilha e outra
stack<string> pilhaCartasAMover;

//Declarando a fila que contém todas as cartas utilizadas no baralho.
deque <string> cartasBaralho;

//Declarando o vetor que contém as 10 pilhas que simulam as 10 colunas de cartas do jogo.
vector <stack <string> > pilhasPrincipais (10);

//Vetor utilizado para saber quantas casas fachadas ainda existem em cada coluna.
vector <int> casasFechadas (10);

//Vetor que contém a sequência das Cartas para comparação.
vector<string> sequenciaCartas (13);

// random generator function:
int myrandom (int i) { return std::rand()%i;}

//Interface dos métodos utilizados no programa
void distribuirCartas();
void embaralharCartas();
void exibirAjuda();
void exibirObjetivoJogo();
void iniciarJogo();
void distribuirCartasNasPilhas();
void moverCartaColuna(int);
int verificarPilhaVazia();
void imprimirCartasNaTela();
int verificarMaiorPilha();
void movendoAsCartas(int, int, int);
bool verificarMovimento(int, int, int);
bool verificarNumero(string, string);
bool verificarColunaOrigem(int, int);
void desfazerPilha(int, int);
void verificarColunaCompleta(int);
//Fim criação das Interfaces

/* Início do método principal do programa Paciência Spider */
int main(int argc, char** argv) {

    int i, nAleatorio;        

    // ************** DEFININDO AS CARTAS *****************

    // PAUS.
    cartasBaralho.push_back(" A-P");
    cartasBaralho.push_back("02-P");
    cartasBaralho.push_back("03-P");
    cartasBaralho.push_back("04-P");
    cartasBaralho.push_back("05-P");
    cartasBaralho.push_back("06-P");
    cartasBaralho.push_back("07-P");
    cartasBaralho.push_back("08-P");
    cartasBaralho.push_back("09-P");
    cartasBaralho.push_back("10-P");
    cartasBaralho.push_back(" J-P");
    cartasBaralho.push_back(" Q-P");
    cartasBaralho.push_back(" K-P");
   
    cartasBaralho.push_back(" A-P");
    cartasBaralho.push_back("02-P");
    cartasBaralho.push_back("03-P");
    cartasBaralho.push_back("04-P");
    cartasBaralho.push_back("05-P");
    cartasBaralho.push_back("06-P");
    cartasBaralho.push_back("07-P");
    cartasBaralho.push_back("08-P");
    cartasBaralho.push_back("09-P");
    cartasBaralho.push_back("10-P");
    cartasBaralho.push_back(" J-P");
    cartasBaralho.push_back(" Q-P");
    cartasBaralho.push_back(" K-P");
    
    // COPAS. 
    cartasBaralho.push_back(" A-C");
    cartasBaralho.push_back("02-C");
    cartasBaralho.push_back("03-C");
    cartasBaralho.push_back("04-C");
    cartasBaralho.push_back("05-C");
    cartasBaralho.push_back("06-C");
    cartasBaralho.push_back("07-C");
    cartasBaralho.push_back("08-C");
    cartasBaralho.push_back("09-C");
    cartasBaralho.push_back("10-C");
    cartasBaralho.push_back(" J-C");
    cartasBaralho.push_back(" Q-C");
    cartasBaralho.push_back(" K-C");
    
    cartasBaralho.push_back(" A-C");
    cartasBaralho.push_back("02-C");
    cartasBaralho.push_back("03-C");
    cartasBaralho.push_back("04-C");
    cartasBaralho.push_back("05-C");
    cartasBaralho.push_back("06-C");
    cartasBaralho.push_back("07-C");
    cartasBaralho.push_back("08-C");
    cartasBaralho.push_back("09-C");
    cartasBaralho.push_back("10-C");
    cartasBaralho.push_back(" J-C");
    cartasBaralho.push_back(" Q-C");
    cartasBaralho.push_back(" K-C");
    
    // ESPADA.
    cartasBaralho.push_back(" A-E");
    cartasBaralho.push_back("02-E");
    cartasBaralho.push_back("03-E");
    cartasBaralho.push_back("04-E");
    cartasBaralho.push_back("05-E");
    cartasBaralho.push_back("06-E");
    cartasBaralho.push_back("07-E");
    cartasBaralho.push_back("08-E");
    cartasBaralho.push_back("09-E");
    cartasBaralho.push_back("10-E");
    cartasBaralho.push_back(" J-E");
    cartasBaralho.push_back(" Q-E");
    cartasBaralho.push_back(" K-E");

    cartasBaralho.push_back(" A-E");
    cartasBaralho.push_back("02-E");
    cartasBaralho.push_back("03-E");
    cartasBaralho.push_back("04-E");
    cartasBaralho.push_back("05-E");
    cartasBaralho.push_back("06-E");
    cartasBaralho.push_back("07-E");
    cartasBaralho.push_back("08-E");
    cartasBaralho.push_back("09-E");
    cartasBaralho.push_back("10-E");
    cartasBaralho.push_back(" J-E");
    cartasBaralho.push_back(" Q-E");
    cartasBaralho.push_back(" K-E");
    
    // OURO.
    cartasBaralho.push_back(" A-O");
    cartasBaralho.push_back("02-O");
    cartasBaralho.push_back("03-O");
    cartasBaralho.push_back("04-O");
    cartasBaralho.push_back("05-O");
    cartasBaralho.push_back("06-O");
    cartasBaralho.push_back("07-O");
    cartasBaralho.push_back("08-O");
    cartasBaralho.push_back("09-O");
    cartasBaralho.push_back("10-O");
    cartasBaralho.push_back(" J-O");
    cartasBaralho.push_back(" Q-O");
    cartasBaralho.push_back(" K-O");
    
    cartasBaralho.push_back(" A-O");
    cartasBaralho.push_back("02-O");
    cartasBaralho.push_back("03-O");
    cartasBaralho.push_back("04-O");
    cartasBaralho.push_back("05-O");
    cartasBaralho.push_back("06-O");
    cartasBaralho.push_back("07-O");
    cartasBaralho.push_back("08-O");
    cartasBaralho.push_back("09-O");
    cartasBaralho.push_back("10-O");
    cartasBaralho.push_back(" J-O");
    cartasBaralho.push_back(" Q-O");
    cartasBaralho.push_back(" K-O");            

    // ************** FIM DEFINIÃ‡ÃƒO DE CARTAS *****************            
            
    // Criação da sequência que será utilizada para comparação nas colunas.
    sequenciaCartas[0] = " A";
    sequenciaCartas[1] = "02";
    sequenciaCartas[2] = "03";
    sequenciaCartas[3] = "04";
    sequenciaCartas[4] = "05";
    sequenciaCartas[5] = "06";
    sequenciaCartas[6] = "07";
    sequenciaCartas[7] = "08";
    sequenciaCartas[8] = "09";
    sequenciaCartas[9] = "10";
    sequenciaCartas[10] = " J";
    sequenciaCartas[11] = " Q";
    sequenciaCartas[12] = " K";
    
    int opcaoMenu;
    
    //Menu principal do Jogo.
    do{
    
        cout << "Bem vindo ao jogo Paciencia Spider !   " << endl;
        cout << "Digite a opcao desejada:" << endl;
        cout << " " << endl;
        cout << "1) Novo jogo" << endl;
        cout << "2) Ajuda" << endl;
        cout << "3) Objetivo do jogo" << endl;
        cout << "0) Sair" << endl;
        cout << "Opcao: ";
        cin >> opcaoMenu;
    
        switch (opcaoMenu)
        {
            //Opção caso o usuário deseje começar um novo jogo.
            case 1:
                                
                embaralharCartas();
                distribuirCartas();
                
                iniciarJogo();
                
                break;
            
            //Opção para obter ajuda no jogo.
            case 2:
                // COMANDO PARA LIMPAR A TELA.
                cout << "\033[2J" << endl;
                
                // Chama o procedimento para exibir a ajuda pro usuario.
                exibirAjuda();
                
                // FORCAR PAUSAR TELA AQUI
                getchar();getchar();
                
                break;
            
            //Opção para saber sobre o objetivo do jogo
            case 3:
                // COMANDO PARA LIMPAR A TELA.
                cout << "\033[2J" << endl;
                
                // Chama o procedimento para exibir o objetivo pro usuario.
                exibirObjetivoJogo();
                
                // FORCAR PAUSAR TELA AQUI
                getchar();getchar();
                
                break;
                          
            //Opção para finalizar o jogo.
            case 0:
                cout << "Obrigado por jogar o Paciencia Spider!";
            break;
            
            //Opção caso o usuário selecione uma opção inválida.
            default:
                cout << "Opção inválida. Tente novamente." << endl;
                break;
    }
    
    }while(opcaoMenu != 0);
       
    return 0;
}
//Método utilizado para a exibição da opção ajuda para o Usuário.
void exibirAjuda(){
    
                cout << "- Ajuda - Paciencia Spider -" << endl;
                cout << " " << endl;
                cout << "Este jogo foi desenvolvido exclusivamente para a disciplina de Estrutura de Dados - ProfÃ‚Âº Roberto Ferrari Jr." << endl;
                cout << "Para jogar o paciencia Spider e necessario apertar a tecla '1' no menu principal, logo depois havera 104 "
                        "cartas no tabuleiro (02 baralhos completos), distribuidas de forma aleatoria em 10 pilhas principais, e 4 "
                        "pilhas secundarias que poderam ser utilizadas de acordo com a necessidade do jogador. "  << endl;
                
                cout << "\n\n\n\n";
                

                cout << "Trabalho desenvolvido por: " << endl;
                cout << " " << endl;
                cout << "Camila Monteiro Caetano Tomaz           RA: 48.184-0" << endl;
                cout << "Icaro de Paula                          RA: XX.XXX-X" << endl;
                cout << "Jonas de Castro                         RA: 48.222-6" << endl;
                cout << " " << endl;
                cout << "Pressione qualquer tecla para voltar ao menu principal . . . " << endl;
    
    
}

//Método utilizado para imprimir o objetivo do jogo
void exibirObjetivoJogo(){
    
                cout << "- OBJETIVO DO JOGO -" << endl;
                cout << " " << endl;
                
                cout << "O objetivo do Paciencia Spider ÃƒÂ© empilhar as cartas de forma decrescente (K, Q, J, 10, 9, 8, 7, 6, 5, 4, 3, 2, A" << endl;
                cout << "Formando 8 grupos o player vencera." << endl;
                        
                cout << " " << endl;
                cout << " " << endl;
                
                cout << "  - - - - - - -   " << "  - - - - - - -   " << "  - - - - - - -   " << "  - - - - - - -   " << endl;
                cout << " |              | " << " |              | " << " |K            K| " << " |9            9| " << endl;
                cout << " |              | " << " |              | " << " |--------------| " << " |--------------| " << endl;
                cout << " |              | " << " |              | " << " |Q            Q| " << " |8            8| " << endl;
                cout << " |              | " << " |              | " << " |--------------| " << " |--------------| " << endl;
                cout << " |              | " << " |              | " << " |J            J| " << " |7            7| " << endl;
                cout << " |              | " << " |              | " << " |--------------| " << " |--------------| " << endl;
                cout << " |              | " << " |              | " << " |10          10| " << " |6            6| " << endl;
                cout << " |              | " << " |              | " << " |              | " << " |--------------| " << endl;
                cout << "  - - - - - - -   " << "  - - - - - - -   " << " |              | " << " |5            5| " << endl;
                cout << "                  " << "                  " << " |              | " << " |--------------| " << endl;
                cout << "                  " << "                  " << " |              | " << " |4            4| " << endl;
                cout << "                  " << "                  " << " |              | " << " |--------------| " << endl;
                cout << "                  " << "                  " << " |              | " << " |3            3| " << endl;
                cout << "                  " << "                  " << " |10          10| " << " |--------------| " << endl;
                cout << "                  " << "                  " << "  --------------  " << " |2            2| " << endl;          
                cout << "                  " << "                  " << "                  " << " |--------------| " << endl;
                cout << "                  " << "                  " << "        ^         " << " |A            A| " << endl;
                cout << "                  " << "                  " << "        |         " << " |              | " << endl;
                cout << "                  " << "                  " << "        |         " << " |              | " << endl;
                cout << "                  " << "                  " << "        |         " << " |              | " << endl;
                cout << "                  " << "                  " << "        |         " << " |              | " << endl;
                cout << "                  " << "                  " << "        |         " << " |              | " << endl;
                cout << "                  " << "                  " << "        |         " << " |              | " << endl;
                cout << "                  " << "                  " << "        |         " << " |A            A| " << endl;
                cout << "                  " << "                  " << "        |         " << "  --------------  " << endl;
                cout << "                  " << "                  " << "        |         " << "                  " << endl;                        
                cout << "                  " << "                  " << "        |         " << "         |        " << endl;
                cout << "                  " << "                  " << "        |         " << "         |        " << endl;
                cout << "                  " << "                  " << "        |         " << "         |        " << endl;
                cout << "                  " << "                  " << "        | _ _ _ _ " << " _ _ _  /         " << endl;
                cout << " " << endl;
                cout << "                                                       Mover a pilha da esquerda, para a direita." << endl;
                cout << "                                                            Os valores estao em sequencia." << endl;
                
                
                
                
                
                cout << "           - -  > Conjuntos ja montados.          " << endl;
                cout << "         /          " << endl;
                cout << "        |           " << endl;
                cout << "        |           " << endl;
                cout << "        |           " << endl;
                cout << "        |           " << endl;
                cout << "        |           " << endl;
                
                cout << "  - - - - - - - - - - " << endl;
                cout << " |K|K|K|K|K|K      K| " << endl;
                cout << " | | | | | |        | " << endl;
                cout << " | | | | | |        | " << endl;
                cout << " | | | | | |        | " << endl;
                cout << " | | | | | |        | " << endl;
                cout << " | | | | | |        | " << endl;
                cout << " |K|K|K|K|K|K      K| " << endl;
                cout << "  - - - - - - - - - - " << endl;
    
}
//Definição do método que irá embaralhar as Cartas
void embaralharCartas(){

    //int contador = 0;
    
    srand ( unsigned ( std::time(0) ) );

    // using built-in random generator:
    std::random_shuffle ( cartasBaralho.begin(), cartasBaralho.end() );

    // using myrandom:
    std::random_shuffle ( cartasBaralho.begin(), cartasBaralho.end(), myrandom);

    // print out content:

    for (std::deque<string>::iterator it=cartasBaralho.begin(); it!=cartasBaralho.end(); ++it)
    {    
        pilhaEmbaralhada.push(*it);
    }

}

//Criação do método que irá realizar a distribuição das cartas
void distribuirCartas(){

    //Distribuindo as Cartas para as pilhas maiores
    for(int i = 0; i < 50; i++){
        
        pilhaAuxiliar.push(pilhaEmbaralhada.top());
        pilhaEmbaralhada.pop();
    }
    
    //Distribuindo as cartas para as pilhas menores
    for(int i = 0; i < 5; i++){
        for(int j = 0; j < 10; j++){
            pilhasPrincipais.at(j).push(pilhaEmbaralhada.top());
            pilhaEmbaralhada.pop();
        }
    }
    
    //Distribuição para as 4 colunas que terão uma carta a mais
    for(int i = 0; i < 4; i++){

        pilhasPrincipais.at(i).push(pilhaEmbaralhada.top());
        pilhaEmbaralhada.pop();

    }

    // Inicialização da quantidade de casas fechadas.
    casasFechadas[0] = 5;
    casasFechadas[1] = 5;
    casasFechadas[2] = 5;
    casasFechadas[3] = 5;
    casasFechadas[4] = 4;
    casasFechadas[5] = 4;
    casasFechadas[6] = 4;
    casasFechadas[7] = 4;
    casasFechadas[8] = 4;
    casasFechadas[9] = 4;

    cout << "cartas distribuidas " << endl;
}

// Método utilizado para inicializar um jogo
void iniciarJogo(){
    
    int opcao;
    int fimJogo = 0;
    
    while(fimJogo == 0){

        //Aqui serão impressas as cartas na tela
        imprimirCartasNaTela();
        
        cout << "O que deseja fazer?" << endl;
        cout << "Abrir cartas auxiliares (0)" << endl;
        cout << "Escolher uma coluna (1 a 10)" << endl;
        cout << "Finalizar (-1)" << endl;
        cin >> opcao;
        
        //Dependendo da opção, podemos finalizar o jogo, distribuir mais cartas
        //para as colunas ou mover as cartas de uma coluna a outra.
        if(opcao == 0){
            distribuirCartasNasPilhas();
        }else{
            if(opcao > 0 && opcao <= 10){
                moverCartaColuna(opcao);
            }else{
                if(opcao == -1){
                    fimJogo = 1;
                }else{
                    cout << "Opção Inválida. Tente novamente." << endl;
        
                }
            }
        }
    }
}

//Método utilizado para a distribuição de uma carta para cada coluna, quando
//solicitado pelo usuário.
void distribuirCartasNasPilhas(){

    //Verificação de que não existe uma pilha vazia ou que a pilha de cartas
    //para distribuição esteja vazia.
    if((verificarPilhaVazia() != 0) || (pilhaAuxiliar.empty())){


        cout << "Existe uma coluna vazia, ou nÃ£o possui mais cartas auxiliares! A movimentaÃ§Ã£o nÃ£o pode ser realizada." << endl;	

    }else{
	    for(int i = 0; i < 10; i ++){
            pilhasPrincipais.at(i).push(pilhaAuxiliar.top());
            pilhaAuxiliar.pop();
        }


    }
}

//Método que irá retornar a informação de que existe ou não uma pilha vazia
int verificarPilhaVazia(){

    int temPilhaVazia = 0;

    for(int i = 0; i < 10; i++){
       
        if(pilhasPrincipais.at(i).size() == 0){
            temPilhaVazia += 1;
        }
        
    }

    if(temPilhaVazia > 0){
        return 1;
    }else{
        return 0;
    }
    
}

// Método que fará a impressão das cartas na tela.
void imprimirCartasNaTela(){
    
    int qtde;
    int maiorPilha = verificarMaiorPilha();

    vector <stack <string> > pilhasAuxs (10);
    
    for(int i = 0; i < 10; i++){
        qtde = pilhasPrincipais.at(i).size();
        for(int j = 0; j < qtde; j++){
            pilhasAuxs.at(i).push(pilhasPrincipais.at(i).top());
            pilhasPrincipais.at(i).pop();
        }
    }
    
    //Inicío da Impressão das Cartas
    cout << "*************************  Jogo Paciencia  **************************" << endl;
    cout << "Col1   Col2    Col3   Col4   Col5   Col6   Col7   Col8   Col9   Col10" << endl;
    
    for(int i = 0; i < maiorPilha; i++){

        vector<string> cartas (10);
        
        for(int j = 0; j < 10; j ++){
            if(pilhasAuxs.at(j).size() != 0){
                    
                pilhasPrincipais.at(j).push(pilhasAuxs.at(j).top());
                pilhasAuxs.at(j).pop();
                
                // Caso a carta esteja após a última carta fechada, ela será 
                // impressa aberta na tela
                if(casasFechadas[j] < pilhasPrincipais.at(j).size()){
                    cartas.at(j) = (string) pilhasPrincipais.at(j).top();
                // Caso a carta esteja antes ou seja a última carta fechada
                // será impressa apenas a informação de que existe uma carta ali.
                }else{
                    cartas.at(j) = "XXXX";
                }
            //Caso nesta posição não tenha carta serão impresso espaços para
            //esta representação.
            }else{
                cartas.at(j) = "    ";
            }
            
            cout << cartas.at(j) << "   ";
        }
        cout << " " << endl;
    }
    
    cout << "  " << endl;
    
}

//Método utilizado para obter a quantidade de cartas da maior pilha.
int verificarMaiorPilha(){
    
    int maior = 0;
    
    for(int i = 0; i < 10; i++){
        if(pilhasPrincipais.at(i).size() > maior){
            maior = pilhasPrincipais.at(i).size();
        }
    }

    return maior;
    
}

//Método utilizado para verificar se a quantidade de cartas solicitadas para 
//movimentação não é maior que a quantidade de cartas disponíveis na coluna
bool verificarQuantidadeCartas(int cartas, int qualColuna){


    if(pilhasPrincipais.at(qualColuna - 1).size() >= cartas){
        return true;
    }else{
        return false;
    }
            
}

//Método utilizado para realizar o movimento de uma coluna a outra.
void moverCartaColuna(int coluna){


    int qtdeCartas, colunaDestino;
   
    cout << "Deseja mover quantas cartas da coluna " << coluna << " ?" << endl;
    cin >> qtdeCartas;

    if (verificarQuantidadeCartas(qtdeCartas, coluna) == true) {
        cout << "Deseja mover " << qtdeCartas << " cartas da coluna " << coluna << " para qual coluna? " << endl;
        cin >> colunaDestino;
                    
        if ((colunaDestino < 0) && (colunaDestino > 10)){
            cout << "Coluna invalida! Digite um valor entre 0 e 10." << endl;
        } else {
            movendoAsCartas(coluna, qtdeCartas, colunaDestino);
            cout << "Cartas movidas com sucesso! " << endl;
        }
    } else {
        cout << "Voce esta selecionando mais cartas do que ha na pilha!" << endl;
    }   
}

//Método que realiza a movimentação das cartas
void movendoAsCartas(int colunaOrigem, int cartasMover, int colunaDeDestino){
    
    int i;
    
    if(!verificarMovimento(colunaOrigem, cartasMover, colunaDeDestino)){
        cout << "Movimento Inválido." << endl;
    }else{
        
        for (i = (cartasMover - 1); i >= 0; i--){
        
            pilhasPrincipais.at(colunaDeDestino - 1).push(pilhaCartasAMover.top());
            pilhaCartasAMover.pop();
            
            verificarColunaCompleta(colunaDeDestino);

        }
        
        if(casasFechadas[colunaOrigem - 1] == pilhasPrincipais.at(colunaOrigem - 1).size()){
            casasFechadas[colunaOrigem - 1] -= 1;
        }
    }
}

//Método utilizado para a verificação do movimento, retornando se ele é possível ou não
bool verificarMovimento(int colunaOrigem, int cartasMover, int colunaDestino){
    
    string cartaOrigem;
    string numeroOrigem;
    string cartaDestino;
    string numeroDestino;

    if(verificarColunaOrigem(colunaOrigem, cartasMover)){

        cartaOrigem = pilhaCartasAMover.top();
        numeroOrigem.append(cartaOrigem, 0, 2);    
    
        if(pilhasPrincipais.at(colunaDestino -1).size() > 0){
            cartaDestino = pilhasPrincipais.at(colunaDestino - 1).top();
            numeroDestino.append(cartaDestino, 0, 2);    
    
            if(verificarNumero(numeroOrigem, numeroDestino)){
                return true;
            }else{
                desfazerPilha(cartasMover, colunaOrigem);
                return false;
            }
        }else{
            return true;
        }        
    }else{
        return false;
    }
}

//Método utilizado para verificar se as cartas a serem movimentadas estão em 
//posição correta para movimentação e se o naipe de todas são iguais.
bool verificarColunaOrigem(int colunaOrigem, int cartasMover){
    
    int fim = 0;
    int i = 0;
    
    string cartaOrigem;
    string numeroOrigem;
    string naipeOrigem;
    string cartaDestino;
    string numeroDestino;
    string naipeDestino;
        
    while(i < cartasMover && fim == 0){        
        
        pilhaCartasAMover.push(pilhasPrincipais.at(colunaOrigem - 1).top());
        pilhasPrincipais.at(colunaOrigem - 1).pop();
        
        if(i < (cartasMover - 1)){

            cartaOrigem = pilhaCartasAMover.top();
            numeroOrigem.append(cartaOrigem, 0, 2);   
            naipeOrigem.append(cartaOrigem, 3, 1);
    
            cartaDestino = pilhasPrincipais.at(colunaOrigem - 1).top();
            numeroDestino.append(cartaDestino, 0, 2);    
            naipeDestino.append(cartaDestino, 3, 1);
    
            if(!verificarNumero(numeroOrigem, numeroDestino) ||
                naipeOrigem != naipeDestino){
                fim = 1;
            }
        }      
        
        i += 1;
    }
    
    if (fim == 1){
        desfazerPilha(i, colunaOrigem);
        return false;
    }else{
        return true;
    }
}

//Método que retorna as informações para a pilha original quando algum movimento
//inválido foi realizado
void desfazerPilha(int qtde, int coluna){

        for (int j = 0; j < qtde; j++){
            pilhasPrincipais.at(coluna - 1).push(pilhaCartasAMover.top());
            pilhaCartasAMover.pop();
        }    
}

//Método utilizado para veriticar se a carta de origem pode ser movida para a
//carta de destino, analisando o número das duas cartas
bool verificarNumero(string numeroOrigem, string numeroDestino){

    if((numeroOrigem == " A" && numeroDestino != "02")||
       (numeroOrigem == "02" && numeroDestino != "03")||
       (numeroOrigem == "03" && numeroDestino != "04")||
       (numeroOrigem == "04" && numeroDestino != "05")||
       (numeroOrigem == "05" && numeroDestino != "06")||
       (numeroOrigem == "06" && numeroDestino != "07")||
       (numeroOrigem == "07" && numeroDestino != "08")||
       (numeroOrigem == "08" && numeroDestino != "09")||
       (numeroOrigem == "09" && numeroDestino != "10")||
       (numeroOrigem == "10" && numeroDestino != " J")||
       (numeroOrigem == " J" && numeroDestino != " Q")||
       (numeroOrigem == " Q" && numeroDestino != " K")||
       (numeroOrigem == " K")){
        
        return false;
    
    }else{
        return true;
    }
    
}

//Método que verifica se a coluna está completa e a retira da pilha.
void verificarColunaCompleta(int colunaDestino){

    int i = 0;
    int fim = 0;
    string carta;
    string numero;
    string naipe;
    string naipeAtual;
    
    carta = pilhasPrincipais.at(colunaDestino - 1).top();
    numero.append(carta, 0, 2);
    naipe.append(carta, 3, 1);
    naipeAtual.append(carta, 3, 1);
    
    while(i < 13 && fim == 0){ 
        
        if(numero == sequenciaCartas.at(i) && naipe == naipeAtual){

            pilhaCartasAMover.push(pilhasPrincipais.at(colunaDestino - 1).top());
            pilhasPrincipais.at(colunaDestino - 1).pop();

            if(i < 12){
                carta = pilhasPrincipais.at(colunaDestino - 1).top();
                numero = "";
                numero.append(carta, 0, 2);
                naipeAtual = "";
                naipeAtual.append(carta, 3, 1);    
            }
            
        }else{
            fim = 1;
            
        }
        
        i += 1;
        
    }
    
    if(fim == 1 && i > 1){
        desfazerPilha(i - 1, colunaDestino);
    }else{
        if(casasFechadas[colunaDestino - 1] > 0){
            casasFechadas[colunaDestino - 1] -= 1;
        }

    }
}
